package client;

import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

import additions.*;

public class ClientInterface extends JFrame {

    private Client client;
    JList listUsers;
    JList listConversations;
    //Holds references to all message windows
    protected Vector messageWindows;
    //Provides mapping of tab number to clientId
    protected Vector tabToClient;
    protected JButton buttonSend;
    protected JTextField textMessage;
    protected JScrollPane scrollUsers;
    protected JScrollPane scrollConversations;
    protected JMenuBar menuBar;
    protected JMenu tabMenu;
    protected JMenu fileMenu;
    protected JMenuItem exitFMenu;
    protected JMenuItem connectFMenu;
    protected JTabbedPane tbChatWindows;
    protected JToolBar tbarMain;
    protected JButton buttonLogin;
    protected JButton buttonExit;
    protected JButton buttonConfigure;
    protected JButton buttonInvite;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JList jList1;
    private javax.swing.JList jList2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JToolBar jToolBar1;

    ClientInterface(Client client) {
        super("Lemon Goose Client");
        this.client = client;

        setUpMenu();
        setUpMainInterface();
        initComponents();

        setVisible(true);
        textMessage.requestFocus();

    }

    private void initComponents() {

        jScrollPane3 = new javax.swing.JScrollPane();
        jList2 = new javax.swing.JList();
        jButton1 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        jToolBar1 = new javax.swing.JToolBar();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        jButton5 = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jScrollPane2 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jList2.setModel(new javax.swing.AbstractListModel() {

            String[] strings = {"Contact 1", "Contact 2", "Contact 3", "Contact 4", "Contact 5"};

            public int getSize() {
                return strings.length;
            }

            public Object getElementAt(int i) {
                return strings[i];
            }
        });
        jScrollPane3.setViewportView(jList2);

        jButton1.setText("jButton1");

        jTextField1.setText("jTextField1");

        jToolBar1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jToolBar1.setRollover(true);
        jToolBar1.add(jSeparator1);

        jButton3.setText("Login");
        jButton3.setFocusable(false);
        jButton3.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton3.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
//        jButton3.addActionListener(new java.awt.event.ActionListener() {
//            public void actionPerformed(java.awt.event.ActionEvent evt) {
//                jButton3ActionPerformed(evt);
//            }
//        });
        jToolBar1.add(jButton3);

        jButton4.setText("Chat");
        jButton4.setFocusable(false);
        jButton4.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton4.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
//        jButton4.addActionListener(new java.awt.event.ActionListener() {
//            public void actionPerformed(java.awt.event.ActionEvent evt) {
//                jButton4ActionPerformed(evt);
//            }
//        });
        jToolBar1.add(jButton4);

        jButton2.setText("Search");
        jButton2.setFocusable(false);
        jButton2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                System.out.println("test");
            }
        });
        jToolBar1.add(jButton2);
        jToolBar1.add(jSeparator2);

        jButton5.setText("Delete");
        jButton5.setFocusable(false);
        jButton5.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton5.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton5);

        jTabbedPane1.setAlignmentY(-25);

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jTabbedPane1.addTab("tab1", jScrollPane1);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE));
        jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 316, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jList1.setModel(new javax.swing.AbstractListModel() {

            String[] strings = {"Conversation 1", "Conversation 2", "Conversation 3", "Conversation 4", "Conversation 5"};

            public int getSize() {
                return strings.length;
            }

            public Object getElementAt(int i) {
                return strings[i];
            }
        });
        jScrollPane2.setViewportView(jList1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addGroup(layout.createSequentialGroup().addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 344, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jButton1))).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false).addComponent(jScrollPane2).addComponent(jToolBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE)))));
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE)).addGroup(layout.createSequentialGroup().addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(jButton1)))).addContainerGap()));

        pack();
    }

    protected void setUpMenu() {
        exitFMenu = new JMenuItem("Exit", KeyEvent.VK_X);
        connectFMenu = new JMenuItem("Connect", KeyEvent.VK_C);

        fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        fileMenu.add(connectFMenu);
        fileMenu.addSeparator();
        fileMenu.add(exitFMenu);

        menuBar = new JMenuBar();
        menuBar.add(fileMenu);
        setJMenuBar(menuBar);
    }

    protected void setUpListeners() {
        exitFMenu.addActionListener(new ExitButton());
        connectFMenu.addActionListener(new ConnectFMenu());

        buttonSend.addActionListener(new SendButton());
        textMessage.addActionListener(new SendMessage());

        listUsers.addMouseListener(new SelectClient());
        addWindowListener(new OnExit());
    }

    protected void setUpProperties() {
        setSize(575, 500);
        setResizable(false);

        buttonSend.setEnabled(false);
        buttonSend.setToolTipText("Send Your Message");

        textMessage.setEnabled(false);
        textMessage.setToolTipText("Enter Your Message Here");

        listUsers.setFixedCellWidth(101);
        listUsers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        listConversations.setFixedCellWidth(101);
        listConversations.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        scrollUsers = new JScrollPane(listUsers);
        scrollUsers.setColumnHeaderView(new JLabel("Online Users"));

        scrollConversations = new JScrollPane(listConversations);
        scrollConversations.setColumnHeaderView(new JLabel("Conversations"));


        setUpListeners();
    }

    protected void setUpMainInterface() {
        buttonSend = new JButton("       Send       ");

        textMessage = new JTextField(32);
        listUsers = new JList();
        listConversations = new JList();

        setUpTabs();
        setUpProperties();

        Box displayBox = Box.createHorizontalBox();
        displayBox.add(tbChatWindows);
        displayBox.add(Box.createHorizontalStrut(3));
        displayBox.add(scrollUsers);

        Box commandBox = Box.createHorizontalBox();
        commandBox.add(textMessage);
        commandBox.add(Box.createHorizontalStrut(3));
        commandBox.add(buttonSend);
        commandBox.add(scrollConversations);

        Container cp = this.getContentPane();
        cp.setLayout(new FlowLayout(FlowLayout.LEFT));
        cp.add(displayBox);
        cp.add(commandBox);
    }

    protected void setUpTabs() {
        messageWindows = new Vector(5, 2);
        tabToClient = new Vector(5, 2);
        tbChatWindows = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

        //Set up the main tab
        messageWindows.addElement(new JTextArea(10, 30));
        ((JTextArea) messageWindows.elementAt(0)).setLineWrap(true);
        ((JTextArea) messageWindows.elementAt(0)).setEditable(false);

        tbChatWindows.addTab("Main", new JScrollPane((JTextArea) messageWindows.elementAt(0),
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));

        tbChatWindows.setIconAt(0, new ImageIcon("icons/usmenu.gif"));
    //tbChatWindows.setForegroundAt( 0, Color.BLUE );
    }

    //Open a tab to chat with specified friend
    void openNewTab(int friendId) {
        //Check if a conversation tab is already open for the friend
        //If yes then set focus to that tab
        int index = tabToClient.indexOf(new Integer(friendId));
        if (index != -1) {
            tbChatWindows.setSelectedIndex(index);
            return;
        }

        //Open a new conversation tab
        messageWindows.addElement(new JTextArea(10, 30));
        tabToClient.addElement(new Integer(friendId));
        ((JTextArea) messageWindows.lastElement()).setLineWrap(true);
        ((JTextArea) messageWindows.lastElement()).setEditable(false);
        listUsers.setSelectedIndex(friendId);
        tbChatWindows.addTab((String) listUsers.getSelectedValue(), (new JScrollPane((JTextArea) messageWindows.lastElement())));
        tbChatWindows.setIconAt(tabToClient.size(), new ImageIcon("icons/aol.gif"));

        tabMenu.setEnabled(true);

    }

    private void showMessage(int tabSelected, String message) {
        ((JTextArea) messageWindows.elementAt(tabSelected)).append(message);
    }

    void showMessage(Message userMsg) {
        int tabIndex = 0;

        if (((Message) userMsg).isPublic == true) {
            ((JTextArea) messageWindows.elementAt(tabIndex)).append(((Message) userMsg).message + "\n");
        } else {
            tabIndex = tabToClient.indexOf(new Integer(((Message) userMsg).senderId));

            ((JTextArea) messageWindows.elementAt(tabIndex + 1)).append(((Message) userMsg).message + "\n");
        }
    }

    protected void sendMessage() {
        String str = textMessage.getText();
        int tabSelected = tbChatWindows.getSelectedIndex();

        if (str.length() != 0) {
            try {
                if (tabSelected == 0) {
                    client.sendPublicMessage(str);
                } else {
                    Integer clientIndex = (Integer) tabToClient.elementAt(tabSelected - 1);
                    client.sendPrivateMessage(clientIndex.intValue(), str);
                    ((JTextArea) messageWindows.elementAt(tabSelected)).append(client.Name + " says > " + str + "\n");
                }
            } catch (IOException ex) {
                showMessage(tabSelected, "\n\nCannot Send Message...\n\n");
            }
            textMessage.setText("");
        }
    }

    //Close all conversation tabs except the main chat room
    protected void closeAllTabs() {
        int index = 1;
        while (index != tbChatWindows.getTabCount()) {
            tbChatWindows.removeTabAt(index);
            messageWindows.removeElementAt(index);
        }
        tabToClient.clear();

        tabMenu.setEnabled(false);
    }

    //Show effects of disconnection on the interface
    synchronized void notifyDisconnect() {
        connectFMenu.setEnabled(true);
        textMessage.setEnabled(false);
        buttonSend.setEnabled(false);
        closeAllTabs();
        listUsers.setEnabled(false);
    }

    void notifyUserLeft(String clientName) {
        int friendId = client.clientList.indexOf(clientName);
        int index = tabToClient.indexOf(new Integer(friendId));

        //If no conversation tab for the specified user
        if (index == -1) {
            return;
        }

        JOptionPane.showMessageDialog(client.window, clientName + " Has Logged Out",
                "User Left", JOptionPane.INFORMATION_MESSAGE);

        tbChatWindows.removeTabAt(index + 1);
        messageWindows.removeElementAt(index + 1);
        tabToClient.removeElementAt(index);

        //If only the main room tab is left disable the tab menu
        if (tbChatWindows.getTabCount() == 1) {
            tabMenu.setEnabled(false);

        }
    }

    class OnExit extends WindowAdapter implements WindowListener {

        public void windowClosing(WindowEvent we) {
            client.shutDown();
        }

        //Make textField get the focus whenever frame is activated.
        public void windowActivated(WindowEvent e) {
            textMessage.requestFocus();
        }
    }

    class CloseTabButton implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            int index = tbChatWindows.getSelectedIndex();
            if (index != 0) {
                tbChatWindows.removeTabAt(index);
                messageWindows.removeElementAt(index);
                tabToClient.removeElementAt(index - 1);

                if (tbChatWindows.getTabCount() == 1) {
                    tabMenu.setEnabled(false);

                }
            }
        }
    }

    class CloseAllTabsMenu implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            closeAllTabs();
        }
    }

    class ExitButton implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            client.shutDown();
        }
    }

    class SendButton implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            sendMessage();
            textMessage.requestFocus();
        }
    }

    class SendMessage implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            sendMessage();
        }
    }

    class SelectClient extends MouseAdapter implements MouseListener {

        public void mouseClicked(MouseEvent e) {
            if (!listUsers.isSelectionEmpty()) {
                if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
                    openNewTab(listUsers.getSelectedIndex());
                    client.sendChatRequest(listUsers.getSelectedIndex());
                }
            }
        }
    }

    class ConnectFMenu implements ActionListener {

        public void actionPerformed(ActionEvent e) {
//			do
//			{
//				client.Name = JOptionPane.showInputDialog( client.window,"Enter Login Name ?");
//			}

            new ClientLogIn();

//			while( (client.Name==null || client.Name.length()==0) );

            if (client.connectToServer()) {
                client.window.setTitle("Fruit Cha(a)t Plate <--> " + client.Name);

                if (listUsers.getModel() != client.clientList) {
                    listUsers.setModel(client.clientList);
                }

                connectFMenu.setEnabled(false);
//				disconnectFMenu.setEnabled( true );
                textMessage.setEnabled(true);
                buttonSend.setEnabled(true);
                listUsers.setEnabled(true);
                ((JTextArea) messageWindows.elementAt(0)).setText("");
                textMessage.requestFocus();
            }
        }
    }

    class DisconnectFMenu implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            client.disconnectFromServer(true);
            notifyDisconnect();
        }
    }


    //CREATES AND DISPLAYS THE LOGIN DIALOG
    class ClientLogIn extends JDialog {

        JButton buttonOK = new JButton("Login");
        JButton buttonCancel = new JButton("Cancel");
        JLabel labelPort = new JLabel("Port Number: ");
        JLabel labelAddress = new JLabel("Server Address: ");
        JLabel labelUsername = new JLabel("Username");
        JLabel labelPassword = new JLabel("Password");
        JTextField textAddress = new JTextField(12);
        JTextField textPort = new JTextField(6);
        JTextField textUsername = new JTextField(20);
        JPasswordField textPassword = new JPasswordField(20);

        ClientLogIn() {
            super(client.window, "Login", true);

            Box buttonBox = Box.createHorizontalBox();
            buttonBox.add(Box.createHorizontalStrut(15));
            buttonBox.add(buttonOK);
            buttonBox.add(buttonCancel);

            Container jcp = this.getContentPane();
            jcp.setLayout(new FlowLayout(FlowLayout.LEFT));
            jcp.add(labelUsername);
            jcp.add(textUsername);
            jcp.add(labelPassword);
            jcp.add(textPassword);
            jcp.add(labelPort);
            jcp.add(textPort);
            jcp.add(labelAddress);
            jcp.add(textAddress);
            jcp.add(buttonBox);

//			buttonOK.addActionListener( new OKButton() );
            buttonCancel.addActionListener(new CancelButton());

//			server.getConfiguration();

            textPort.setText(Integer.toString(1313));
//			tfLimit.setText( Integer.toString( server.serverLimit ) );

            this.setSize(250, 250);

            Point position = client.window.getLocation();
            position.x = position.x + (client.window.getWidth() / 2) - (this.getWidth() / 2);
            position.y = position.y + (client.window.getHeight() / 2) - (this.getHeight() / 2);
            this.setLocation(position);

            this.setVisible(true);
            this.setResizable(false);
        }

//		class OKButton implements ActionListener
//		{
//			public void actionPerformed( ActionEvent e )
//			{
//
//			}
//		}
        class CancelButton implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        }
    }
}